package com.th.apicenter.vivo.service;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.th.apicenter.config.ApplicationProperties;
import com.th.apicenter.deduct.entity.ThDeduct;
import com.th.apicenter.kuaishou.service.KuaiShouService;
import com.th.apicenter.mapper.ThDeductMapper;
import com.th.apicenter.mapper.ThVIVODataMapper;
import com.th.apicenter.vivo.dto.ThVIVONumDTO;
import com.th.apicenter.vivo.dto.VIVOBehaviorUploadDTO;
import com.th.apicenter.vivo.entity.ThVivoData;
import com.th.apicenter.vivo.vo.VIVOBehaviorUploadVO;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class VIVOService {

    @Resource
    private ThVIVODataMapper thVIVODataMapper;

    @Resource
    private ThDeductMapper thDeductMapper;

    @Resource
    private KuaiShouService kuaiShouService;

    @Resource
    private ApplicationProperties applicationProperties;


    /**
     * 20250428 vivo目前只有真回传
     *
     * @param thVivoData
     */
    public void monitor(ThVivoData thVivoData) throws IOException {
        thVivoData.setCreateTime(new Date());
        thVivoData.setUpdateTime(new Date());
        thVIVODataMapper.insert(thVivoData);
        log.info("接收到vivo的数据：{}", thVivoData);
        ThDeduct thDeduct = thDeductMapper.selectOne(new QueryWrapper<ThDeduct>()
                .eq("account_id", thVivoData.getAccountId())
                .eq("type", "vivo"));
        if (null != thDeduct && thDeduct.getIsTrue() == 0) {
            kuaiShouService.clickVivo(thVivoData, thDeduct);
        } else if (null != thDeduct && thDeduct.getIsTrue() == 1) {
            //假回传 - 咸鱼
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String date = formatter.format(currentTime);
            String startTime = date + " 00:00:00";
            String endTime = date + " 23:59:59";
            ThVIVONumDTO thVIVONumDTO = thVIVODataMapper.queryNumByDate(thVivoData.getAccountId(), startTime, endTime);
            if (thVIVONumDTO.getPassbackNum() >= 1) {
                BigDecimal x = new BigDecimal(thVIVONumDTO.getPassbackNum()).divide(new BigDecimal(thVIVONumDTO.getEffectiveNum()), 2, RoundingMode.CEILING);
                BigDecimal percent = new BigDecimal(thDeduct.getPercent()).divide(new BigDecimal(100), 2, RoundingMode.CEILING);
                if (percent.doubleValue() != 0 && new BigDecimal(1).subtract(x).compareTo(percent) < 0) {
                    log.info("需要扣量，不做操作!");
                    thVivoData.setIsDeduct(1);
                } else {
                    VIVOBehaviorUploadVO vo = behaviorUploadByXianYu(thVivoData, thDeduct, "1", "Web");
                    if ("70100".equals(vo.getCode())) {
                        vo = behaviorUploadByXianYu(thVivoData, thDeduct, "1", "APP");
                    }
                    if ("0".equals(vo.getCode())) {
                        thVivoData.setIsVivoPassback(1);
                    }
                }
            } else {
                VIVOBehaviorUploadVO vo = behaviorUploadByXianYu(thVivoData, thDeduct, "1", "Web");
                if ("70100".equals(vo.getCode())) {
                    vo = behaviorUpload(thVivoData, thDeduct, "1", "APP");
                }
                if ("0".equals(vo.getCode())) {
                    thVivoData.setIsVivoPassback(1);
                }
            }
            thVivoData.setUpdateTime(new Date());
            thVIVODataMapper.updateById(thVivoData);
        }
    }


    public void callback(String actionType, String vivoId) throws IOException {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String date = formatter.format(currentTime);
        String startTime = date + " 00:00:00";
        String endTime = date + " 23:59:59";

        ThVivoData thVivoData = thVIVODataMapper.selectById(vivoId);
        if (null != thVivoData) {
            thVivoData.setIsKsCallback(1);
            thVivoData.setKsActionType(actionType);
            ThDeduct thDeduct = thDeductMapper.selectOne(new QueryWrapper<ThDeduct>()
                    .eq("type", "vivo")
                    .eq("account_id", thVivoData.getAccountId()));
            //判断是否扣量
            ThVIVONumDTO thVIVONumDTO = thVIVODataMapper.queryNumByDate(thVivoData.getAccountId(), startTime, endTime);
            if (thVIVONumDTO.getPassbackNum() >= 10) {
                BigDecimal x = new BigDecimal(thVIVONumDTO.getPassbackNum()).divide(new BigDecimal(thVIVONumDTO.getEffectiveNum()), 2, RoundingMode.CEILING);
                BigDecimal percent = new BigDecimal(thDeduct.getPercent()).divide(new BigDecimal(100), 2, RoundingMode.CEILING);
                if (percent.doubleValue() != 0 && new BigDecimal(1).subtract(x).compareTo(percent) < 0) {
                    log.info("需要扣量，不做操作!");
                    thVivoData.setIsDeduct(1);
                } else {
                    VIVOBehaviorUploadVO vo = behaviorUpload(thVivoData, thDeduct, actionType, "Web");
                    if ("70100".equals(vo.getCode())) {
                        vo = behaviorUpload(thVivoData, thDeduct, actionType, "APP");
                    }
                    if ("0".equals(vo.getCode())) {
                        thVivoData.setIsVivoPassback(1);
                    }
                }
            } else {
                VIVOBehaviorUploadVO vo = behaviorUpload(thVivoData, thDeduct, actionType, "Web");
                if ("70100".equals(vo.getCode())) {
                    vo = behaviorUpload(thVivoData, thDeduct, actionType, "APP");
                }
                if ("0".equals(vo.getCode())) {
                    thVivoData.setIsVivoPassback(1);
                }
            }
            thVivoData.setUpdateTime(new Date());
            thVIVODataMapper.updateById(thVivoData);
        } else {
            throw new RuntimeException("账户未配置！");
        }

    }

    /**
     * vivo用户行为数据上传-咸鱼
     *
     * @return
     */
    public VIVOBehaviorUploadVO behaviorUploadByXianYu(ThVivoData thVivoData, ThDeduct thDeduct, String actionType, String userType) throws IOException {
        String cvType = "";
        switch (actionType) {
            case "1":
                cvType = "ACTIVATION";
                break;
            case "2":
                cvType = "RETENTION_1";
                break;
            case "4":
                cvType = "REACTIVATION";
                break;
            default:
                break;
        }
        String timestamp = String.valueOf(System.currentTimeMillis());

        VIVOBehaviorUploadDTO vivoBehaviorUploadDTO = new VIVOBehaviorUploadDTO();
        VIVOBehaviorUploadDTO.DataList dataList = new VIVOBehaviorUploadDTO.DataList();
        List<VIVOBehaviorUploadDTO.DataList> list = new ArrayList<>();

        dataList.setCreativeId(thVivoData.getCreativeid());
        dataList.setRequestId(thVivoData.getRequestid());
        dataList.setCvType(cvType);
        dataList.setCvTime(timestamp);
        if (!"__IMEI__".equals(thVivoData.getImei()) && !"".equals(thVivoData.getImei()) && null != thVivoData.getImei()) {
            dataList.setUserIdType("IMEI_MD5");
            dataList.setUserId(thVivoData.getImei());
        }
        if (!"__OAID__".equals(thVivoData.getOaid()) && (null == dataList.getUserId())) {
            dataList.setUserIdType("OAID_MD5");
            dataList.setUserId(thVivoData.getOaid());
        }
        list.add(dataList);

        vivoBehaviorUploadDTO.setSrcType(userType.equals("Web") ? "Web" : "APP");
        vivoBehaviorUploadDTO.setPageUrl("https://2.taobao.com");
        vivoBehaviorUploadDTO.setPkgName("com.taobao.idlefish");
        vivoBehaviorUploadDTO.setSrcId(thVivoData.getSrcId());
        vivoBehaviorUploadDTO.setDataList(list);

        String url = applicationProperties.getVivo().getUploadUrl();
        String advertiserId = thVivoData.getAdvertiserid();
        String nonce = IdUtil.simpleUUID();
        String accessToken = thDeduct.getVivoToken();
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(vivoBehaviorUploadDTO);
        log.info("vivo用户行为上传数据：{}", jsonObject);

        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/json");
        String jsonStr = jsonObject.toJSONString(); //使用请求参数的json串替换，格式如下方示例

        RequestBody body = RequestBody.create(mediaType, jsonStr);
        Request request = new Request.Builder()
                .url(url + "?access_token=" + accessToken + "&timestamp=" + timestamp + "&nonce=" + nonce + "&advertiser_id=" + advertiserId)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        log.info("vivo返回的数据：{}", responseBody);
        ObjectMapper mapper = new ObjectMapper();
        VIVOBehaviorUploadVO vivoBehaviorUploadVO = mapper.readValue(responseBody, VIVOBehaviorUploadVO.class);
        return vivoBehaviorUploadVO;
    }

    /**
     * vivo用户行为数据上传
     *
     * @return
     */
    public VIVOBehaviorUploadVO behaviorUpload(ThVivoData thVivoData, ThDeduct thDeduct, String actionType, String userType) throws IOException {
        String cvType = "";
        switch (actionType) {
            case "1":
                cvType = "ACTIVATION";
                break;
            case "2":
                cvType = "RETENTION_1";
                break;
            case "4":
                cvType = "REACTIVATION";
                break;
            default:
                break;
        }
        String timestamp = String.valueOf(System.currentTimeMillis());

        VIVOBehaviorUploadDTO vivoBehaviorUploadDTO = new VIVOBehaviorUploadDTO();
        VIVOBehaviorUploadDTO.DataList dataList = new VIVOBehaviorUploadDTO.DataList();
        List<VIVOBehaviorUploadDTO.DataList> list = new ArrayList<>();

        dataList.setCreativeId(thVivoData.getCreativeid());
        dataList.setRequestId(thVivoData.getRequestid());
        dataList.setCvType(cvType);
        dataList.setCvTime(timestamp);
        if (!"__IMEI__".equals(thVivoData.getImei()) && !"".equals(thVivoData.getImei()) && null != thVivoData.getImei()) {
            dataList.setUserIdType("IMEI_MD5");
            dataList.setUserId(thVivoData.getImei());
        }
        if (!"__OAID__".equals(thVivoData.getOaid()) && (null == dataList.getUserId())) {
            dataList.setUserIdType("OAID_MD5");
            dataList.setUserId(thVivoData.getOaid());
        }
        list.add(dataList);

        vivoBehaviorUploadDTO.setSrcType(userType.equals("Web") ? "Web" : "APP");
        vivoBehaviorUploadDTO.setPageUrl("https://www.kuaishou.com/new-reco");
        vivoBehaviorUploadDTO.setPkgName("com.kuaishou.nebula");
        vivoBehaviorUploadDTO.setSrcId(thVivoData.getSrcId());
        vivoBehaviorUploadDTO.setDataList(list);

        String url = applicationProperties.getVivo().getUploadUrl();
        String advertiserId = thVivoData.getAdvertiserid();
        String nonce = IdUtil.simpleUUID();
        String accessToken = thDeduct.getVivoToken();
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(vivoBehaviorUploadDTO);
        log.info("vivo用户行为上传数据：{}", jsonObject);

        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/json");
        String jsonStr = jsonObject.toJSONString(); //使用请求参数的json串替换，格式如下方示例

        RequestBody body = RequestBody.create(mediaType, jsonStr);
        Request request = new Request.Builder()
                .url(url + "?access_token=" + accessToken + "&timestamp=" + timestamp + "&nonce=" + nonce + "&advertiser_id=" + advertiserId)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        log.info("vivo返回的数据：{}", responseBody);
        ObjectMapper mapper = new ObjectMapper();
        VIVOBehaviorUploadVO vivoBehaviorUploadVO = mapper.readValue(responseBody, VIVOBehaviorUploadVO.class);
        return vivoBehaviorUploadVO;
    }
}
